package org.gcoat.analysis;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class JavaGCLogParser {
	static final int R = 37; // length of "Application time: 0.1234567 seconds\r\n"
	static final int S = 74; // length of "Total time for which application threads were stopped: 0.1234567 seconds\r\n"
	static final int SmR = S - R, RpS = R + S;
	private Pattern[] patterns_ = {
			Pattern.compile(".*Application time: (\\d*\\.\\d*) seconds.*"),
			Pattern.compile(".*Total time for which application threads were stopped: (\\d*\\.\\d*) seconds.*"),
	};

	public void parse(File gclog, GCLogHandler handler) throws IOException {
		int mode = GCLogHandler.RUNNING;
		try (LineNumberReader reader = new LineNumberReader(new InputStreamReader(new FileInputStream(gclog)))) {
			String line;
			while ((line = reader.readLine()) != null) {
				Matcher matcher;
				matcher = patterns_[mode].matcher(line);
				if (matcher.matches()) {
					long time = extractNanoTime(matcher);
					handler.append(mode, time, reader.getLineNumber());
					mode = 1 - mode;
				} else {
					int invm = 1 - mode;
					matcher = patterns_[invm].matcher(line);
					if (matcher.matches()) {
						long time = extractNanoTime(matcher);
						handler.append(invm, time, reader.getLineNumber());
					}
				}
			}
		}
	}

	long extractNanoTime(Matcher matcher) {
		return Math.round(Double.parseDouble(matcher.group(1)) * 1e9);
	}

	public int estimateNumberOfEntries(File gclog) {
		return (int) (2 * gclog.length() + SmR) / RpS;
	}
}
